#-*- coding: utf-8 -*-
#
# Copyright (C) 2010, Muslim Adel Abu Taha <qtprojectcreator@qtprojectcreator>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# $Id: generator.py 38 2010-10-08 19:20:30Z muslim $
# $Rev: 38 $
# $LastChangedDate: 2010-10-08 22:20:30 +0300 (Fri, 08 Oct 2010) $
# $LastChangedBy: muslim $


import os
import sys
import re
import shutil
import pkg_resources
from ConfigParser import RawConfigParser as ConfigParser

from qtprojectcreator import _config


class CreateProject:
    def __init__(self, data):
        
        self.data = data
        self.create_project_base()
        self.write_config_file()
        
    
    def create_project_base(self):
        
        beginning_letter = re.compile(r"^[^a-z]*")
        valid_only = re.compile(r"[^a-z0-9_]")
        
        self.project_name = self.data['project_name']
        
        # This will create safe names without spaces like: 'my-personal-project'
        self.safe_name = pkg_resources.safe_name(self.project_name)
        
        # We need a name for the main package of the project
        self.package_name = self.project_name.lower()
        self.package_name = beginning_letter.sub("", self.package_name)
        self.package_name = valid_only.sub("", self.package_name)
        
        # Define paths
        self.project_dir = os.path.join(os.path.realpath('.'), self.safe_name)
        self.data_dir = os.path.join(self.project_dir, 'data')
        self.icons_dir = os.path.join(self.data_dir, 'icons')
        self.docs_dir = os.path.join(self.data_dir, 'docs')
        self.binaries_dir = os.path.join(self.project_dir, 'bin')
        self.ui_dir = os.path.join(self.project_dir, 'UI')
        self.package_dir = os.path.join(self.project_dir, self.package_name)        
        self.modules_dir = os.path.join(self.package_dir, 'modules')
        self.gui_dir = os.path.join(self.package_dir, 'gui')
        self.ready_dir = os.path.join(self.project_dir, 'ready')
        self.config_file = os.path.join(self.package_dir, 'config.py')
        self.bin_name = self.package_name + '-bin.py'

        for folder in (self.project_dir, self.data_dir, self.icons_dir, \
                self.binaries_dir, self.ui_dir, self.docs_dir, \
                self.package_dir, self.modules_dir, self.gui_dir, \
                self.ready_dir):
            try:
                os.mkdir(folder)
            except OSError:
                print
                print "ERROR: Project '<%s>' already exist in the current directory" % self.project_name
                sys.exit(1)
                break
            

    def touch(self, fn):
        f = open(fn, 'w').close()

    def write_config_file(self):
        for f in ('AUTHORS', 'LICENSE', 'README', 'INSTALL', 'CHANGELOG'):
            self.touch(os.path.join(self.docs_dir, f))
        
        fhandler = open(self.config_file, 'w')
        fhandler.write("""#-*- coding: utf-8 -*-\n\n
# DO NOT EDIT THIS FILE BY HAND!!
#
# THIS FILE IS AUTO-GENERATED DURING PROJECT INSTALLATION
# OR DURING PROJECT CREATION AND IT'S UPDATED AUTOMATICALLY 
# 

DATA_DIR = "%s"
ICONS_DIR = "%s"
DOCS_DIR = "%s"
BIN_DIR = "%s"
PROJ_DIR = "%s"
READY_DIR = "%s"
BIN_NAME = "%s"
""" %(self.data_dir, self.icons_dir, self.docs_dir, \
      self.binaries_dir, self.project_dir, self.ready_dir, self.bin_name))
        
        fhandler.close()
        
        # Write new Config file
        iniconffile = os.path.join(self.project_dir, 'qt_project_config.ini')
        iniconf = ConfigParser()

        iniconf.add_section('information')
        iniconf.set('information', 'website', self.data['website'])
        iniconf.set('information', 'email', self.data['email'])
        iniconf.set('information', 'full_name', self.data['full_name'])
        iniconf.set('information', 'PROJECT_NAME', self.data['project_name'])
        iniconf.set('information', 'LICENSE', self.data['license'])
        iniconf.set('information', 'SHORT_DESCRIPTION', self.data['short_desc'])
        iniconf.set('information', 'LONG_DESCRIPTION', self.data['long_desc'])
        iniconf.set('information', 'PACKAGE_NAME', self.package_name)

        iniconf.add_section('project')
        iniconf.set('project', 'DATA_DIR', self.data_dir)
        iniconf.set('project', 'ICONS_DIR', self.icons_dir)
        iniconf.set('project', 'DOCS_DIR', self.docs_dir)
        iniconf.set('project', 'READY_DIR', self.ready_dir)
        iniconf.set('project', 'BIN_DIR', self.binaries_dir)
        iniconf.set('project', 'PROJ_DIR', self.project_dir)
        iniconf.set('project', 'GUI_DIR', self.gui_dir)
        iniconf.set('project', 'UI_DIR', self.ui_dir)
        iniconf.set('project', 'OS', self.data['OS'])
        iniconf.set('project', 'MODULES_DIR', self.modules_dir)
        iniconf.set('project', 'BIN_NAME', self.bin_name)

        with open(iniconffile, 'wb') as ini_file:
            iniconf.write(ini_file)


    def generate_pyqt_data_from_template(self):
        
        # Write initial files
        fname0 = open(os.path.join(self.package_dir, '__init__.py'), 'w')
        fname0.write('#-*- coding: utf-8 -*-\n\n')
        fname0.close()
        
        fname1 = open(os.path.join(self.modules_dir, '__init__.py'), 'w')
        fname1.write('#-*- coding: utf-8 -*-\n\n__all__ = [ "about" ]\n')
        fname1.close()
        
        fname2 = open(os.path.join(self.gui_dir, '__init__.py'), 'w')
        fname2.write('#-*- coding: utf-8 -*-\n\n__all__ = [ "MainWindow", "about" ]\n')
        fname2.close()
        
        data_to_change = {
            "FULLNAME" : self.data['full_name'],
            "EMAIL" : self.data['email'],
            "PACKAGE_NAME" : self.package_name,
            "PROJECT_NAME" : self.data['project_name'],
            "SHORT_DESC" : self.data['short_desc'],
        }
        
        # Create executable file
        exec_tmpl = file(os.path.join(_config.PYQT4_DIR, 'binary.py')).read()
        p_exec_fname = self.package_name + '-bin.py'
        fhandler = open(os.path.join(self.binaries_dir, p_exec_fname), 'w')
        fhandler.write(exec_tmpl % data_to_change)
        fhandler.close()
        
        # Create controller file
        ctrl_tmpl = file(os.path.join(_config.PYQT4_DIR, 'controller.py')).read()
        p_ctrl = open(os.path.join(self.package_dir, 'controller.py'), 'w')
        p_ctrl.write(ctrl_tmpl % data_to_change)
        p_ctrl.close()
        
        # Create about file
        about_tmpl = file(os.path.join(_config.PYQT4_DIR, 'about.py')).read()
        p_about = open(os.path.join(self.modules_dir, 'about.py'), 'w')
        p_about.write(about_tmpl % data_to_change)
        p_about.close()
        
        # Copy some icons
        save_icon = os.path.join(_config.ICONS_DIR, 'save.png')
        exit_icon = os.path.join(_config.ICONS_DIR, 'exit.png')
        
        for icon in (save_icon, exit_icon):
            shutil.copy(icon, self.icons_dir)
        
        # Copy designer 'ui' files
        tmpl_main_ui_file = os.path.join(_config.UI_DIR, 'MainWindow.ui')
        tmpl_about_ui_file = os.path.join(_config.UI_DIR, 'about.ui')
        
        for ui in (tmpl_main_ui_file, tmpl_about_ui_file):
            shutil.copy(ui, self.ui_dir)
        
        # Compile designer 'ui' files
        mainwindow_ui_file = os.path.join(self.ui_dir, 'MainWindow.ui')
        mainwindow_py_file = os.path.join(self.gui_dir, 'MainWindow.py')
        cmd0 = "%s %s -o %s" %(_config.PYUIC4, mainwindow_ui_file, mainwindow_py_file)
        
        about_ui_file = os.path.join(self.ui_dir, 'about.ui')
        about_py_file = os.path.join(self.gui_dir, 'about.py')
        cmd1 = "%s %s -o %s" %(_config.PYUIC4, about_ui_file, about_py_file)
        
        for cmd in (cmd0, cmd1):
            os.system(cmd)
        
        shutil.copy(os.path.join(_config.DATA_DIR, 'manage.py'), self.project_dir)

